module pci_decoder(
	wr_port,
	rd_port,
	pci_addr,
	pci_ads_n,
	pci_wr_n,
	pci_clk,
	pci_blast_n,
	pci_rdy_n,
	pci_hold,
	pci_holda
);

input[8:0] pci_addr;//地址总线
input pci_ads_n;//开始数据传输
input pci_wr_n;//读写控制位 =0为本地总线到PCIE方向
input pci_clk;//本地总线系统时钟
input pci_blast_n;//最后一次数据传输
input pci_hold;//本地总线请求信号

output reg pci_holda;//本地总线请求响应信号
output pci_rdy_n;//指示读取的数据或者要写入的数据会在下一个时钟的上升沿被采样
output[111:0] wr_port;//写端口译码
output[111:0] rd_port;//读端口译码

reg[8:0] lock_addr;

//总线占用请求及响应电路模块（始终响应请求）
always@(posedge pci_clk)
	begin
		pci_holda <= pci_hold;
	end

//PCI总线总处于准备好状态（始终准备采样）
assign pci_rdy_n = 1'b0;

//数据传输开始时，地址锁存（pci_ads_n==0）
always@(negedge pci_clk)
begin
	if(!pci_ads_n)
		lock_addr <= pci_addr;
	else
		lock_addr <= lock_addr;
end

reg[15:0] dec_addr0,dec_addr1,dec_addr2;//地址总线译码结果
reg[15:0] dec_addr3,dec_addr4,dec_addr5,dec_addr6;

//wire[8:0] pre_addr;//只用地址总线其中9位进行译码[10:2]

//assign pre_addr = lock_addr[10:2];

always@(lock_addr)
begin
	dec_addr0 = 16'h0000;
	dec_addr1 = 16'h0000;
	dec_addr2 = 16'h0000;
	dec_addr3 = 16'h0000;
	dec_addr4 = 16'h0000;
	dec_addr5 = 16'h0000;
	dec_addr6 = 16'h0000;
	case(lock_addr)//FPGA1地址空间0x000-0x03F
	9'h000: dec_addr0 = 16'h0001;//0 rw[0]
	9'h001: dec_addr0 = 16'h0002;//4 rw[1]
	9'h002: dec_addr0 = 16'h0004;//8 rw[2]
	9'h003: dec_addr0 = 16'h0008;//c rw[3]
	9'h004: dec_addr0 = 16'h0010;//10 rw[4]
	9'h005: dec_addr0 = 16'h0020;//14 rw[5]
	9'h006: dec_addr0 = 16'h0040;//18 rw[6]
	9'h007: dec_addr0 = 16'h0080;//1c rw[7]
	9'h008: dec_addr0 = 16'h0100;//20 rw[8]
	9'h009: dec_addr0 = 16'h0200;//24 rw[9]
	9'h00a: dec_addr0 = 16'h0400;//28 rw[10]
	9'h00b: dec_addr0 = 16'h0800;//2c rw[11]
	9'h00c: dec_addr0 = 16'h1000;//30 rw[12]
	9'h00d: dec_addr0 = 16'h2000;//34 rw[13]
	9'h00e: dec_addr0 = 16'h4000;//38 rw[14]
	9'h00f: dec_addr0 = 16'h8000;//3c rw[15]

	9'h010: dec_addr1 = 16'h0001;
	9'h011: dec_addr1 = 16'h0002;
	9'h012: dec_addr1 = 16'h0004;
	9'h013: dec_addr1 = 16'h0008;
	9'h014: dec_addr1 = 16'h0010;
	9'h015: dec_addr1 = 16'h0020;
	9'h016: dec_addr1 = 16'h0040;
	9'h017: dec_addr1 = 16'h0080;
	9'h018: dec_addr1 = 16'h0100;
	9'h019: dec_addr1 = 16'h0200;
	9'h01a: dec_addr1 = 16'h0400;
	9'h01b: dec_addr1 = 16'h0800;
	9'h01c: dec_addr1 = 16'h1000;
	9'h01d: dec_addr1 = 16'h2000;
	9'h01e: dec_addr1 = 16'h4000;
	9'h01f: dec_addr1 = 16'h8000;

	9'h020: dec_addr2 = 16'h0001;
	9'h021: dec_addr2 = 16'h0002;
	9'h022: dec_addr2 = 16'h0004;
	9'h023: dec_addr2 = 16'h0008;
	9'h024: dec_addr2 = 16'h0010;
	9'h025: dec_addr2 = 16'h0020;
	9'h026: dec_addr2 = 16'h0040;
	9'h027: dec_addr2 = 16'h0080;
	9'h028: dec_addr2 = 16'h0100;
	9'h029: dec_addr2 = 16'h0200;
	9'h02a: dec_addr2 = 16'h0400;
	9'h02b: dec_addr2 = 16'h0800;
	9'h02c: dec_addr2 = 16'h1000;
	9'h02d: dec_addr2 = 16'h2000;
	9'h02e: dec_addr2 = 16'h4000;
	9'h02f: dec_addr2 = 16'h8000;

	9'h030: dec_addr3 = 16'h0001;
	9'h031: dec_addr3 = 16'h0002;
	9'h032: dec_addr3 = 16'h0004;
	9'h033: dec_addr3 = 16'h0008;
	9'h034: dec_addr3 = 16'h0010;
	9'h035: dec_addr3 = 16'h0020;
	9'h036: dec_addr3 = 16'h0040;
	9'h037: dec_addr3 = 16'h0080;
	9'h038: dec_addr3 = 16'h0100;
	9'h039: dec_addr3 = 16'h0200;
	9'h03a: dec_addr3 = 16'h0400;
	9'h03b: dec_addr3 = 16'h0800;
	9'h03c: dec_addr3 = 16'h1000;
	9'h03d: dec_addr3 = 16'h2000;
	9'h03e: dec_addr3 = 16'h4000;
	9'h03f: dec_addr3 = 16'h8000;

	9'h040: dec_addr4 = 16'h0001;
	9'h041: dec_addr4 = 16'h0002;
	9'h042: dec_addr4 = 16'h0004;
	9'h043: dec_addr4 = 16'h0008;
	9'h044: dec_addr4 = 16'h0010;
	9'h045: dec_addr4 = 16'h0020;
	9'h046: dec_addr4 = 16'h0040;
	9'h047: dec_addr4 = 16'h0080;
	9'h048: dec_addr4 = 16'h0100;
	9'h049: dec_addr4 = 16'h0200;
	9'h04a: dec_addr4 = 16'h0400;
	9'h04b: dec_addr4 = 16'h0800;
	9'h04c: dec_addr4 = 16'h1000;
	9'h04d: dec_addr4 = 16'h2000;
	9'h04e: dec_addr4 = 16'h4000;
	9'h04f: dec_addr4 = 16'h8000;

	9'h050: dec_addr5 = 16'h0001;
	9'h051: dec_addr5 = 16'h0002;
	9'h052: dec_addr5 = 16'h0004;
	9'h053: dec_addr5 = 16'h0008;
	9'h054: dec_addr5 = 16'h0010;
	9'h055: dec_addr5 = 16'h0020;
	9'h056: dec_addr5 = 16'h0040;
	9'h057: dec_addr5 = 16'h0080;
	9'h058: dec_addr5 = 16'h0100;
	9'h059: dec_addr5 = 16'h0200;
	9'h05a: dec_addr5 = 16'h0400;
	9'h05b: dec_addr5 = 16'h0800;
	9'h05c: dec_addr5 = 16'h1000;
	9'h05d: dec_addr5 = 16'h2000;
	9'h05e: dec_addr5 = 16'h4000;
	9'h05f: dec_addr5 = 16'h8000;

	9'h060: dec_addr6 = 16'h0001;
	9'h061: dec_addr6 = 16'h0002;
	9'h062: dec_addr6 = 16'h0004;
	9'h063: dec_addr6 = 16'h0008;
	9'h064: dec_addr6 = 16'h0010;
	9'h065: dec_addr6 = 16'h0020;
	9'h066: dec_addr6 = 16'h0040;
	9'h067: dec_addr6 = 16'h0080;
	9'h068: dec_addr6 = 16'h0100;
	9'h069: dec_addr6 = 16'h0200;
	9'h06a: dec_addr6 = 16'h0400;
	9'h06b: dec_addr6 = 16'h0800;
	9'h06c: dec_addr6 = 16'h1000;
	9'h06d: dec_addr6 = 16'h2000;
	9'h06e: dec_addr6 = 16'h4000;
	9'h06f: dec_addr6 = 16'h8000;


	default: begin
				dec_addr0 = 16'h0000;
				dec_addr1 = 16'h0000;
				dec_addr2 = 16'h0000;
				dec_addr3 = 16'h0000;
				dec_addr4 = 16'h0000;
				dec_addr5 = 16'h0000;
				dec_addr6 = 16'h0000;
			 end
	endcase
end

//读写端口译码
wire[15:0] wr_flag;
reg[15:0] lock_blast;

//读写控制线扩展成16位，以便后面可一次性译码16位
assign wr_flag = pci_wr_n ? 16'hffff : 16'h0000;//1写 0读

always@(negedge pci_clk)
begin
	if(!pci_blast_n)
		lock_blast <= 16'hffff;
	else
		lock_blast <= 16'h0000;
end

assign wr_port[15:0] = dec_addr0 & lock_blast & wr_flag;//112位写端口
assign wr_port[31:16] = dec_addr1 & lock_blast & wr_flag;
assign wr_port[47:32] = dec_addr2 & lock_blast & wr_flag;
assign wr_port[63:48] = dec_addr3 & lock_blast & wr_flag;
assign wr_port[79:64] = dec_addr4 & lock_blast & wr_flag;
assign wr_port[95:80] = dec_addr5 & lock_blast & wr_flag;
assign wr_port[111:96] = dec_addr6 & lock_blast & wr_flag;

assign rd_port[15:0] = (~dec_addr0) | lock_blast | wr_flag;//112位读端口
assign rd_port[31:16] = (~dec_addr1) | lock_blast | wr_flag;
assign rd_port[47:32] = (~dec_addr2) | lock_blast | wr_flag;
assign rd_port[63:48] = (~dec_addr3) | lock_blast | wr_flag;
assign rd_port[79:64] = (~dec_addr4) | lock_blast | wr_flag;
assign rd_port[95:80] = (~dec_addr5) | lock_blast | wr_flag;
assign rd_port[111:96] = (~dec_addr6) | lock_blast | wr_flag;

endmodule
